unit uThreadAction;

interface

uses
  Winapi.Windows, System.SysUtils, System.Classes, Vcl.Forms, Winapi.ShlObj,
  System.Win.ComObj;

type
{$M+}
  TThreadAction = class
{$IFDEF DEBUG}
  private
    function DebugData(bBuffer: TBytes; ShowAnsi: Boolean = True): string;
{$ENDIF}
  private
  published
    procedure Template;
    procedure ID;
    procedure UnlockST;
    procedure UnlockWD;
    procedure Sleep;
    procedure Wake;
  end;
{$M-}

var
  ThreadAction: TThreadAction;

implementation

uses
  uFrmMain, uFrmAction, uCommon, uTaskFile, uSMART;

{$IFDEF DEBUG}

function TThreadAction.DebugData(bBuffer: TBytes; ShowAnsi: Boolean = True): string;
var
  i, j: Integer;
  value: Byte;
  cstr, edit: string;
begin
  edit := edit + '     |00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F|     ANSI ASCII ' + #13;
  edit := edit + '-----------------------------------------------------|----------------' + #13;
  i := 0;
  while i < 512 do
  begin
    cstr := Format('%.04X |', [i]);
    edit := edit + cstr;
    for j := 0 to 15 do
    begin
      value := bBuffer[i + j];
      if j = 15 then
        cstr := Format('%.02X', [value])
      else
        cstr := Format('%.02X ', [value]);
      edit := edit + cstr;
    end;
    if ShowAnsi then
    begin
      edit := edit + '|';
      for j := 0 to 15 do
      begin
        value := bBuffer[i + j];
        if value = 0 then
          cstr := ' '
        else
          cstr := Format('%s', [AnsiString(Chr(value))]);
        edit := edit + cstr;
      end;
    end;
    edit := edit + #13;
    i := i + 16;
  end;
  Result := edit;
end;
{$ENDIF}

procedure TThreadAction.Template;
begin
  try
    FrmAction.IsThreadActive := True;
    if TaskFile.ERR then
      Exit;

  finally
    FrmAction.IsThreadActive := False;
  end;
end;

procedure TThreadAction.ID;
var
  bBuffer: TBytes;
  uFlag: Word;
  fDataIncomplete: Boolean;
begin
  try
    FrmAction.IsThreadActive := True;
    if TaskFile.ERR then
      Exit;
    SetLength(bBuffer, 512);
    if not TaskFile.GetIdentify(bBuffer) then
      Exit;
{$IFDEF DEBUG}
    FrmAction.redtHDD.Lines.Add(DebugData(bBuffer));
{$ENDIF}
    uFlag := bBuffer[0] + bBuffer[1] shl 8;
    if uFlag <> $848A then
    begin
      //fDataIncomplete := (bBuffer[2] = 0) and (bBuffer[3] = 0);
      fDataIncomplete := uFlag and 4 = 4;
    end
    else
    begin
      uFlag := bBuffer[2] + bBuffer[3] shl 8;
      fDataIncomplete := (uFlag = $37C8) or (uFlag = $738C) or (uFlag = $8C73) or (uFlag = $C873);
    end;
    if not fDataIncomplete then
      FrmAction.redtHDD.Lines.Add(TaskFile.IDENT(bBuffer, fMoreInfo))
    else
      FrmAction.redtHDD.Lines.Add('Drive Identify Data Is Incomplete!' + #13#10);
  finally
    FrmAction.IsThreadActive := False;
    SetLength(bBuffer, 0);
  end;
end;

procedure TThreadAction.UnlockST;
var
  strPassword: string;
  bfrPassword: TBytes;
  i: Integer;
begin
  try
    FrmAction.IsThreadActive := True;
    if TaskFile.ERR then
      Exit;
    FrmAction.redtHDD.Lines.Add('SECURITY UNLOCK ST HIGH');
    FrmAction.redtHDD.Lines.Add('--------------------------------');
    FrmAction.redtHDD.Lines.Add(' - SECURITY UNLOCK');
    if not TaskFile.UnlockUnit then
    begin
      FrmAction.redtHDD.Lines.Add(' - Error' + #13#10);
      Exit;
    end;
    SetLength(bfrPassword, 512);
    bfrPassword[0] := 1;
    strPassword := 'SeaGate.........................';
    for i := 1 to Length(strPassword) do
      bfrPassword[i + 1] := Byte(strPassword[i]);
    FrmAction.redtHDD.Lines.Add(' - Compare Maximum Password');
    FrmAction.redtHDD.Lines.Add(' - ' + strPassword);
    if not TaskFile.WriteDataFromBuffer(bfrPassword) then
      Exit;
    if not TaskFile.WaitNotBSY() then
      Exit;
    if TaskFile.ERR then
    begin
      FrmAction.redtHDD.Lines.Add(' - Error');
      Exit;
    end
    else
      FrmAction.redtHDD.Lines.Add(' - Success');
    FrmAction.redtHDD.Lines.Add(' - SECURITY DISABLE PASSWORD');
    if not TaskFile.DisablePWD then
    begin
      FrmAction.redtHDD.Lines.Add(' - Error' + #13#10);
      Exit;
    end;
    FrmAction.redtHDD.Lines.Add(' - Compare Maximum Password');
    FrmAction.redtHDD.Lines.Add(' - ' + strPassword);
    if not TaskFile.WriteDataFromBuffer(bfrPassword) then
      Exit;
    if not TaskFile.WaitNotBSY() then
      Exit;
    if TaskFile.ERR then
      FrmAction.redtHDD.Lines.Add(' - Error' + #13#10)
    else
      FrmAction.redtHDD.Lines.Add(' - Success' + #13#10);
  finally
    FrmAction.IsThreadActive := False;
    SetLength(bfrPassword, 0);
  end;
end;

procedure TThreadAction.UnlockWD;
var
  strPassword: string;
  bfrPassword: TBytes;
  i: Integer;
begin
  try
    FrmAction.IsThreadActive := True;
    if TaskFile.ERR then
      Exit;
    FrmAction.redtHDD.Lines.Add('SECURITY UNLOCK WD HIGH');
    FrmAction.redtHDD.Lines.Add('--------------------------------');
    FrmAction.redtHDD.Lines.Add(' - SECURITY UNLOCK');
    if not TaskFile.UnlockUnit then
    begin
      FrmAction.redtHDD.Lines.Add(' - Error' + #13#10);
      Exit;
    end;
    SetLength(bfrPassword, 512);
    bfrPassword[0] := 1;
    strPassword := 'WDCWDCWDCWDCWDCWDCWDCWDCWDCWDCW';
    for i := 1 to Length(strPassword) do
      bfrPassword[i + 1] := Byte(strPassword[i]);
    FrmAction.redtHDD.Lines.Add(' - Compare Maximum Password');
    FrmAction.redtHDD.Lines.Add(' - ' + strPassword);
    if not TaskFile.WriteDataFromBuffer(bfrPassword) then
      Exit;
    if not TaskFile.WaitNotBSY() then
      Exit;
    if TaskFile.ERR then
    begin
      FrmAction.redtHDD.Lines.Add(' - Error');
      Exit;
    end
    else
      FrmAction.redtHDD.Lines.Add(' - Success');
    FrmAction.redtHDD.Lines.Add(' - SECURITY DISABLE PASSWORD');
    if not TaskFile.DisablePWD then
    begin
      FrmAction.redtHDD.Lines.Add(' - Error' + #13#10);
      Exit;
    end;
    FrmAction.redtHDD.Lines.Add(' - Compare Maximum Password');
    FrmAction.redtHDD.Lines.Add(' - ' + strPassword);
    if not TaskFile.WriteDataFromBuffer(bfrPassword) then
      Exit;
    if not TaskFile.WaitNotBSY() then
      Exit;
    if TaskFile.ERR then
      FrmAction.redtHDD.Lines.Add(' - Error' + #13#10)
    else
      FrmAction.redtHDD.Lines.Add(' - Success' + #13#10);
  finally
    FrmAction.IsThreadActive := False;
    SetLength(bfrPassword, 0);
  end;
end;

procedure TThreadAction.Sleep;
begin
  try
    FrmAction.IsThreadActive := True;
    if TaskFile.ERR then
      Exit;
    FrmAction.redtHDD.Lines.Add('SLEEP DRIVE');
    FrmAction.redtHDD.Lines.Add('--------------------------------');
    if not TaskFile.SleepDrive then
      FrmAction.redtHDD.Lines.Add(' - Error' + #13#10)
    else
      FrmAction.redtHDD.Lines.Add(' - Success' + #13#10);
  finally
    FrmAction.IsThreadActive := False;
  end;
end;

procedure TThreadAction.Wake;
begin
  try
    FrmAction.IsThreadActive := True;
    if TaskFile.ERR then
      Exit;
    FrmAction.redtHDD.Lines.Add('WAKE DRIVE');
    FrmAction.redtHDD.Lines.Add('--------------------------------');
    if not TaskFile.WakeDrive then
      FrmAction.redtHDD.Lines.Add(' - Error' + #13#10)
    else
      FrmAction.redtHDD.Lines.Add(' - Success' + #13#10);
  finally
    FrmAction.IsThreadActive := False;
  end;
end;

end.

